#include <QtCore>

#include "boardfigure.h"
#include "constants.h"

BoardFigure::BoardFigure( int x, int y, QString pixmap_path, int color, QGraphicsItem* parent ) : BoardItem( x, y, pixmap_path, parent )
{
  this->color = color;
  setZValue( getDefaultZValue() );
  possibleMoves.clear();
  attackedFields.clear();
  possibleMovesReady = false;
  attackedFieldsReady = false;
  moveCount = 0;
}

void BoardFigure::move(int newX, int newY, BoardFigure* board[8][8])
{
  BoardFigure* item = board[x][y];
  if ( board[newX][newY] ) {
    delete board[newX][newY];
  }
  board[newX][newY] = item;
  board[x][y] = 0;

  x = newX;
  y = newY;

  calculateSelfScenePos();
  setPos( scenePos );

  moveCount++;
  // clear all possible moves and attacked fields
  // for all figures
  for ( int i=0; i < Constants::BOARD_SIZE; i++ ) {
    for ( int j=0; j < Constants::BOARD_SIZE; j++ ) {
      if ( board[i][j] ) {
        board[i][j]->clearPossibleMoves();
        board[i][j]->clearAttackedFields();
      }
    }
  }

}

bool BoardFigure::checkNewPos( int newX, int newY )
{
  bool result = true;
  if ( newX < 0 || newX > Constants::BOARD_SIZE - 1
       || newY < 0 || newY > Constants::BOARD_SIZE - 1
     ) result = false;
    
  return result;
}

void BoardFigure::generateMovesFromVectors( int* dx, int* dy, int size, BoardFigure* board[8][8] )
{
  int x = getBoardX(), y = getBoardY();
  qDebug() << "Generating moves from vectors";
  for ( int i = 0; i < size; i++ ) {
    qDebug() << "Vector#" << i;
    int newDX = dx[i], newDY = dy[i];
    while ( checkNewPos(x + newDX, y + newDY)
            && ( board[x + newDX][y + newDY] == 0
                 ||
                 board[x + newDX][y + newDY]->getColor() != getColor()
               )
          ) {
      qDebug() << "DX:" << newDX << " DY:" << newDY; 
      Move* move = new Move( x, y, x + newDX, y + newDY );
      possibleMoves.push_back( move );
      
      if ( board[x + newDX][y + newDY] != 0 ) break;
      newDX += dx[i];
      newDY += dy[i];
      qDebug() << "NEWDX:" << newDX << " NEWDY:" << newDY;
    }
  }
}

bool BoardFigure::isFieldUnderAttackByColor(int x, int y, int color, BoardFigure* board[8][8] )
{
  qDebug() << "isFieldUnderAttackByColor called: " << x << ", " << y;
  bool result = false;
  for ( int i=0; i < Constants::BOARD_SIZE; i++ ) {
    if ( result ) break;
    for ( int j=0; j < Constants::BOARD_SIZE; j++ ) {
      if ( result ) break;
      BoardFigure* figure = board[i][j];
      if ( figure
           && figure->getColor() == color
         ) {
        qDebug() << "Checking figure on " << i << ", " << j;
        QList<QPoint*> attackedFields = figure->getAttackedFields(board);
        QPoint currentField( x, y );
        for ( int k = 0; k < attackedFields.size(); k++) {
          qDebug() << "Figure attack on:" << attackedFields.at(k)->x() << ", " << attackedFields.at(k)->x();
          if ( attackedFields.at(k)->x() == x && attackedFields.at(k)->y() == y ) {
            result = true;
            break;
          }
        }
      }
    }
  }
  qDebug() << "isFieldUnderAttackByColor finished";
  return result;
}


QList<QPoint*>& BoardFigure::getAttackedFields( BoardFigure* board[8][8] )
{
  if ( attackedFieldsReady ) return attackedFields;

  // Default behavior return all possible moves as attacked fields
  // for pawns there is another behavior
  QList<Move*>& moves = getPossibleMoves( board );
  for ( int i = 0; i < moves.size(); i++ ) {
    QPoint* point = new QPoint( moves.at(i)->getNewX(), moves.at(i)->getNewY() );
    attackedFields.push_back( point );
  }

  attackedFieldsReady = true;
  return attackedFields;
}

void BoardFigure::clearPossibleMoves()
{
  if ( possibleMoves.size() ) {
    for ( int i=0; i < possibleMoves.size(); i++ ) {
      qDebug() << "Deleting possible move at: " << i;
      delete possibleMoves.at(i);
    }
    possibleMoves.clear();
  }
  possibleMovesReady = false;
}


void BoardFigure::clearAttackedFields()
{
  if ( attackedFields.size() ) {
    for ( int i=0; i < attackedFields.size(); i++ ) {
      qDebug() << "Deleting attacked fields at: " << i;
      delete attackedFields.at(i);
    }
    attackedFields.clear();
  }
  attackedFieldsReady = false;
}

BoardFigure::~BoardFigure()
{
  qDebug() << "~~ BoardFigure destructor called";
  clearPossibleMoves();
  clearAttackedFields();
}

int BoardFigure::getDefaultZValue()
{
  return Constants::FIGURE_Z_LEVEL;
}

bool BoardFigure::isMovable()
{
  return 1;
}
